/**
 * 
 */
package org.swing.utility.jai.imgio;

import java.awt.Dimension;
import java.awt.geom.*;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import java.util.Iterator;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;

import org.apache.log4j.Logger;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageDecoder;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * @author Quynh Nhu
 * 
 */
public class ImageIoResize {
	private static Logger log = Logger.getLogger(ImageUtil.class);

	public static void main(String[] arg) throws IOException {
		File inFile = new File(arg[0]);
		File outFile = new File(arg[1]);
		resizeImage(inFile, outFile, 80, 80);
	}

	public static BufferedImage resizeImage(File inFile, File outFile, int w,
			int h) throws IOException {
		BufferedImage imgIn = readJpeg(inFile);
		BufferedImage imgOut = resizeImage(imgIn, w, h);
		writeJpeg(imgOut, outFile, 0.75);
		return imgOut;
	}

	public static BufferedImage resizeImage(InputStream in, OutputStream out,
			int w, int h) throws IOException {
		BufferedImage imgIn = readJpeg(in);
		BufferedImage imgOut = resizeImage(imgIn, w, h);
		writeJpeg(imgOut, out, 0.75);
		return imgOut;
	}

	public static BufferedImage resizeImage(BufferedImage imgIn, int w, int h) {

		int imageType = imgIn.getType();

		double imageWidth = (double) imgIn.getWidth();
		double imageHeight = (double) imgIn.getHeight();

		double sx = (double) w / imageWidth;
		double sy = (double) h / imageHeight;

		int nw, nh;

		if (sx < sy) {
			sy = sx;
			nw = w;
			nh = (int) (imageHeight * sy);
		} else {
			sx = sy;
			nw = (int) (imageWidth * sx);
			nh = h;
		}

		log.debug("" + imageWidth + "x" + imageHeight + " -> " + nw + "x" + nh);

		AffineTransform tx = new AffineTransform();
		tx.scale(sx, sy);

		AffineTransformOp op = new AffineTransformOp(tx,
				AffineTransformOp.TYPE_BILINEAR);
		BufferedImage imgOut = new BufferedImage(nw, nh, imageType);
		return op.filter(imgIn, imgOut);

	}

	public static BufferedImage readJpeg(File jpegFile) throws IOException {
		// return ImageIO.read(jpegFile);
		return readJpeg(new FileInputStream(jpegFile));
	}

	public static BufferedImage readJpeg(InputStream in) throws IOException {
		// return ImageIO.read(in);
		JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(in);
		return decoder.decodeAsBufferedImage();
	}

	public static Dimension getImageDimension(File imageFile)
			throws IOException {
		// BufferedImage img = ImageIO.read(imageFile);
		BufferedImage img = readJpeg(imageFile);
		Dimension d = new Dimension();
		d.setSize(img.getWidth(), img.getHeight());
		return d;
	}

	public static void writeJpeg(BufferedImage imgOut, File outFile,
			double compression) throws IOException {
		writeJpeg(imgOut, new FileOutputStream(outFile), compression);
	}

	public static void writeJpeg(BufferedImage imgOut, OutputStream out,
			double compression) throws IOException {
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
		encoder.encode(imgOut);
	}

	public static void writeJpeg14(BufferedImage imgOut, OutputStream out,
			double compression) throws IOException {
		ImageWriter writer = null;
		Iterator iter = ImageIO.getImageWritersByFormatName("jpg");
		if (iter.hasNext()) {
			writer = (ImageWriter) iter.next();
		}

		ImageWriteParam iwparam = writer.getDefaultWriteParam();
		if (iwparam.canWriteCompressed()) {
			iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
			iwparam.setCompressionQuality((float) compression);
		}

		javax.imageio.stream.ImageOutputStream ios = ImageIO
				.createImageOutputStream(out);
		writer.setOutput(ios);

		// Write the image
		writer.write(null, new IIOImage(imgOut, null, null), iwparam);

		ios.flush();
		writer.dispose();
		ios.close();
	}
	
	
}
